home *** CD-ROM | disk | FTP | other *** search
/ IRIS Performer 2.2 Friends Demo / SGI IRIS Performer 2.2 Friends Demo.iso / friends / openworlds / tix / EFileBox.tcl < prev    next >
Text File  |  1997-11-22  |  12KB  |  485 lines

  1. #
  2. # ToDo
  3. #   (1)    If user has entered an invalid directory, give an error dialog
  4. #
  5.  
  6. tixWidgetClass tixExFileSelectBox {
  7.     -classname TixExFileSelectBox
  8.     -superclass tixPrimitive
  9.     -method {
  10.     filter invoke
  11.     }
  12.     -flag {
  13.     -browsecmd -command -dialog -dir -dircmd -directory 
  14.     -disablecallback -filetypes -pattern -selection -showhidden -value
  15.     }
  16.     -forcecall {
  17.     -filetypes
  18.     }
  19.     -configspec {
  20.     {-browsecmd browseCmd BrowseCmd {}}
  21.     {-command command Command {}}
  22.     {-dialog dialog Dialog {}}
  23.     {-dircmd dirCmd DirCmd {}}
  24.     {-directory directory Directory {}}
  25.     {-disablecallback disableCallback DisableCallback false}
  26.     {-filetypes fileTypes FileTypes {}}
  27.     {-pattern pattern Pattern *}
  28.     {-showhidden showHidden ShowHidden false}
  29.     {-value value Value {}}
  30.     }
  31.     -alias {
  32.     {-dir -directory}
  33.     {-selection -value}
  34.     }
  35.  
  36.     -default {
  37.     {*dir.label             {Directories:}}
  38.     {*dir.editable             true}
  39.     {*dir.history             true}
  40.     {*dir*listbox.height         5}
  41.     {*file.label              Files:}
  42.     {*file.editable         true}
  43.     {*file.history             false}
  44.     {*file*listbox.height         5}
  45.     {*types.label             {List Files of Type:}}
  46.     {*types*listbox.height         3}
  47.     {*TixComboBox.labelSide     top}
  48.     {*TixComboBox*Label.anchor     w}
  49.     {*dir.label.underline         0}
  50.     {*file.label.underline        0}
  51.     {*types.label.underline     14}
  52.     {*TixComboBox.anchor         e}
  53.     {*TixHList.height         7}
  54.     {*filelist*listbox.height     7}
  55.     {*hidden.wrapLength         3c}
  56.     {*hidden.justify         left}
  57.     }
  58. }
  59.  
  60. proc tixExFileSelectBox::InitWidgetRec {w} {
  61.     upvar #0 $w data
  62.     global env
  63.  
  64.     tixChainMethod $w InitWidgetRec
  65.  
  66.     if {$data(-directory) == {}} {
  67.     global env
  68.  
  69.     if {[info exists env(PWD)]} {
  70.         set data(-directory) $env(PWD)
  71.     } else {
  72.         set data(-directory) [pwd]
  73.     }
  74.     }
  75.     set data(oldDir)    {}
  76.     set data(flag)      0
  77. }
  78.  
  79.  
  80. #----------------------------------------------------------------------
  81. #        Construct widget
  82. #----------------------------------------------------------------------
  83. proc tixExFileSelectBox::ConstructWidget {w} {
  84.     upvar #0 $w data
  85.  
  86.     tixChainMethod $w ConstructWidget
  87.  
  88.     # listbox frame
  89.     set lf [frame $w.lf]
  90.  
  91.     # The pane that contains the two listboxes
  92.     #
  93.     set pane  [tixPanedWindow $lf.pane -orientation horizontal]
  94.     set fpane [$pane add 1 -size 160]
  95.     set dpane [$pane add 2 -size 160]
  96.  
  97.     $dpane config -relief flat
  98.     $fpane config -relief flat
  99.  
  100.     # The File List Pane
  101.     #
  102.     set data(w:file)  [tixComboBox $fpane.file\
  103.     -command "tixExFileSelectBox::Cmd-FileCombo $w"\
  104.     -prunehistory true \
  105.     -options { \
  106.         label.anchor w \
  107.     }]
  108.     set data(w:filelist) [tixScrolledListBox $fpane.filelist \
  109.     -command "tixExFileSelectBox::Cmd-FileList $w 1"\
  110.     -browsecmd "tixExFileSelectBox::Cmd-FileList $w 0"]
  111.     pack $data(w:file)  -padx 8 -pady 4 -side top -fill x
  112.     pack $data(w:filelist) -padx 8 -pady 4 -side top -fill both -expand yes
  113.  
  114.     # The Directory Pane
  115.     #
  116.     set data(w:dir)   [tixComboBox $dpane.dir \
  117.     -command "tixExFileSelectBox::Cmd-DirCombo $w"\
  118.     -prunehistory true \
  119.     -options { \
  120.         label.anchor w \
  121.     }]
  122.     set data(w:dirlist) [tixDirList  $dpane.dirlist \
  123.     -command "tixExFileSelectBox::Cmd-DirList $w"\
  124.     -browsecmd "tixExFileSelectBox::Browse-DirList $w"]
  125.     pack $data(w:dir)   -padx 8 -pady 4 -side top -fill x
  126.     pack $data(w:dirlist) -padx 8 -pady 4 -side top -fill both -expand yes
  127.  
  128.     # The file types listbox
  129.     #
  130.     set data(w:types) [tixComboBox $lf.types\
  131.     -command "tixExFileSelectBox::Cmd-TypeCombo $w" \
  132.     -options { \
  133.         label.anchor w \
  134.     }]
  135.  
  136.     pack $data(w:types)  -padx 12 -pady 4 -side bottom -fill x -anchor w
  137.     pack $pane -side top -padx 4 -pady 4 -expand yes -fill both
  138.  
  139.     # Buttons to the right
  140.     #
  141.     set bf [frame $w.bf]
  142.     set data(w:ok)     [button $bf.ok -text OK\
  143.     -underline 0 -command "tixExFileSelectBox::Ok $w"]
  144.     set data(w:cancel) [button $bf.cancel -text Cancel\
  145.     -underline 0 -command "tixExFileSelectBox::Cancel $w"]
  146.     set data(w:hidden) [checkbutton $bf.hidden -text "Show Hidden Files"\
  147.     -underline 0\
  148.            -variable [format %s(-showhidden) $w] -onvalue true -offvalue false\
  149.     -command "tixExFileSelectBox::SetShowHidden $w"]
  150.  
  151.     pack $data(w:ok) $data(w:cancel) $data(w:hidden)\
  152.     -side top -fill x -padx 6 -pady 3
  153.  
  154.     pack $bf -side right -fill both -pady 6
  155.     pack $lf -side left -expand yes -fill both
  156.  
  157.     tixDoWhenMapped $w "tixExFileSelectBox::Map $w"
  158.  
  159.     if {$data(-filetypes) == {}} {
  160.     $data(w:types) config -state disabled
  161.     }
  162. }
  163.  
  164.  
  165. #----------------------------------------------------------------------
  166. # Configuration
  167. #----------------------------------------------------------------------
  168. proc tixExFileSelectBox::config-showhidden {w value} {
  169.     upvar #0 $w data
  170.  
  171.     set data(-showhidden) $value
  172.     tixExFileSelectBox::SetShowHidden $w
  173. }
  174.  
  175. # Update both DirList and {file list and dir combo}
  176. #
  177. #
  178. proc tixExFileSelectBox::config-directory {w value} {
  179.     upvar #0 $w data
  180.  
  181.     set data(-directory) [tixExFileSelectBox::CompressSlash $w $value]
  182.     tixSetSilent $data(w:dirlist) $data(-directory) 
  183.     tixSetSilent $data(w:dir) $data(-directory) 
  184.     tixWidgetDoWhenIdle tixExFileSelectBox::LoadFiles $w reload
  185.  
  186.     return $data(-directory) 
  187. }
  188.  
  189. proc tixExFileSelectBox::config-filetypes {w value} {
  190.     upvar #0 $w data
  191.  
  192.     $data(w:types) subwidget listbox delete 0 end
  193.  
  194.     foreach name [array names data] {
  195.     if [string match type,* $name] {
  196.         catch {unset data($name)}
  197.     }
  198.     }
  199.  
  200.     if {$value == {}} {
  201.     $data(w:types) config -state disabled
  202.     } else {
  203.     $data(w:types) config -state normal
  204.     
  205.     foreach type $value {
  206.         $data(w:types) insert end [lindex $type 1]
  207.         set data(type,[lindex $type 1]) [lindex $type 0]
  208.     }
  209.     tixSetSilent $data(w:types) {}
  210.     }
  211. }
  212.  
  213. #----------------------------------------------------------------------
  214. # MISC Methods
  215. #----------------------------------------------------------------------
  216. proc tixExFileSelectBox::SetShowHidden {w} {
  217.     upvar #0 $w data
  218.  
  219.     $data(w:dirlist) config -showhidden $data(-showhidden)
  220.  
  221.     tixWidgetDoWhenIdle tixExFileSelectBox::LoadFiles $w reload
  222. }
  223.  
  224. # User activates the dir combobox
  225. #
  226. #
  227. proc tixExFileSelectBox::Cmd-DirCombo {w dir} {
  228.     upvar #0 $w data
  229.  
  230.     set dir [tixResolveDir $dir]
  231.     if {[string index $dir 0] != "/"} {
  232.     return
  233.     }
  234.     if {![file isdirectory $dir]} {
  235.     return
  236.     }
  237.  
  238.     $data(w:dirlist) config -value $dir
  239.     set data(-directory) $dir
  240. }
  241.  
  242. # User activates the dir list
  243. #
  244. #
  245. proc tixExFileSelectBox::Cmd-DirList {w dir} {
  246.     upvar #0 $w data
  247.  
  248.     set dir [tixExFileSelectBox::CompressSlash $w $dir]
  249.  
  250.     tixSetSilent $data(w:dir) $dir
  251.     set data(-directory) $dir
  252.  
  253.     tixWidgetDoWhenIdle tixExFileSelectBox::LoadFiles $w noreload
  254. }
  255.  
  256. # User activates the dir list
  257. #
  258. #
  259. proc tixExFileSelectBox::Browse-DirList {w dir} {
  260.     upvar #0 $w data
  261.  
  262.     tixExFileSelectBox::Cmd-DirList $w $dir
  263. }
  264.  
  265. proc tixExFileSelectBox::IsPattern {w string} {
  266.     foreach char [split $string {}] {
  267.     if {$char == "*" || $char == "?" || $char == "\{"  || $char == "\[" } {
  268.         return 1
  269.     }
  270.     }
  271.     return 0
  272. }
  273.  
  274. proc tixExFileSelectBox::Cmd-FileCombo {w value} {
  275.     upvar #0 $w data
  276.  
  277.     if [tixExFileSelectBox::IsPattern $w $value] {
  278.     set data(-pattern) $value
  279.     tixWidgetDoWhenIdle tixExFileSelectBox::LoadFiles $w reload
  280.     } else {
  281.     if {[string index $value 0] != "/"} {
  282.         set data(-value) [tixExFileSelectBox::CompressSlash $w \
  283.         $data(-directory)/$value]
  284.     } else {
  285.         set data(-value) $value
  286.     }
  287.     tixExFileSelectBox::Invoke $w
  288.     }
  289. }
  290.  
  291. proc tixExFileSelectBox::Ok {w} {
  292.     upvar #0 $w data
  293.  
  294.     set value [$data(w:file) cget -value]
  295.     set sel   [$data(w:file) cget -selection]
  296.  
  297.     if {$sel != {}} {
  298.     set value $sel
  299.     }
  300.  
  301.     if [tixExFileSelectBox::IsPattern $w $value] {
  302.     set data(-pattern) $value
  303.     tixWidgetDoWhenIdle tixExFileSelectBox::LoadFiles $w reload
  304.     } else {
  305.     if {[string index $value 0] != "/"} {
  306.         set data(-value) [tixExFileSelectBox::CompressSlash $w \
  307.         $data(-directory)/$value]
  308.     } else {
  309.         set data(-value) $value
  310.     }
  311.     tixExFileSelectBox::Invoke $w
  312.     }
  313. }
  314.  
  315. proc tixExFileSelectBox::Cancel {w} {
  316.     upvar #0 $w data
  317.  
  318.     if {$data(-dialog) != {}} {
  319.     eval $data(-dialog) popdown
  320.     }
  321. }
  322.  
  323. proc tixExFileSelectBox::Invoke {w} {
  324.     upvar #0 $w data
  325.  
  326.     # Save some old history
  327.     #
  328.     $data(w:dir)  addhistory [$data(w:dir) cget -value]
  329.     $data(w:file) addhistory $data(-pattern)
  330.  
  331.     if {$data(-dialog) != {}} {
  332.     eval $data(-dialog) popdown
  333.     }
  334.     if {$data(-command) != {} &&
  335.     ![tixGetBoolean -nocomplain $data(-disablecallback)]} {
  336.     $data(w:file) addhistory $data(-value)
  337.     eval $data(-command) [list $data(-value)]
  338.     }
  339. }
  340.  
  341. proc tixExFileSelectBox::Cmd-FileList {w invoke} {
  342.     upvar #0 $w data
  343.  
  344.     set index [lindex [$data(w:filelist) subwidget listbox curselection] 0]
  345.     if {$index == {}} {
  346.     set index 0
  347.     }
  348.  
  349.     set file [$data(w:filelist) subwidget listbox get $index]
  350.     tixSetSilent $data(w:file) $file
  351.  
  352.     set data(-value) \
  353.     [tixExFileSelectBox::CompressSlash $w $data(-directory)/$file]
  354.  
  355.     if {$invoke == 1} {
  356.     tixExFileSelectBox::Invoke $w
  357.     } else {
  358.     if {$data(-browsecmd) != {}} {
  359.         eval $data(-browsecmd) [list $data(-value)]
  360.     }
  361.     }
  362. }
  363.  
  364. proc tixExFileSelectBox::Cmd-TypeCombo {w value} {
  365.     upvar #0 $w data
  366.  
  367.     if [info exists data(type,$value)] {
  368.     set data(-pattern) $data(type,$value)
  369.     tixWidgetDoWhenIdle tixExFileSelectBox::LoadFiles $w reload
  370.     }
  371. }
  372.  
  373. proc tixExFileSelectBox::LoadFiles {w flag} {
  374.     upvar #0 $w data
  375.  
  376.     if {$flag != "reload" && $data(-directory) == $data(oldDir)} {
  377.     return
  378.     }
  379.  
  380.     if {![winfo ismapped [winfo toplevel $w]]} {
  381.     tixDoWhenMapped [winfo toplevel $w] \
  382.         "tixExFileSelectBox::LoadFiles $w $flag"
  383.     return
  384.     }
  385.  
  386.     set listbox [$data(w:filelist) subwidget listbox]
  387.     $listbox delete 0 end
  388.  
  389.     set appPWD [pwd]
  390.  
  391.     if [catch {cd $data(-directory)} err] {
  392.     # The user has entered an invalid directory
  393.     # %% todo: prompt error, go back to last succeed directory
  394.     cd $appPWD
  395.     return
  396.     }
  397.  
  398.     set data(-value) {}
  399.  
  400.     if {$data(-pattern) == "*" && \
  401.     [tixGetBoolean -nocomplain $data(-showhidden)]} {
  402.         set pattern "* .*"
  403.     } else {
  404.     set pattern $data(-pattern)
  405.     }
  406.  
  407.     set files {}
  408.  
  409.     if {$data(-dircmd) != {}} {
  410.     foreach pat $pattern {
  411.         if [catch { eval lappend files [\
  412.             eval $data(-dircmd) $data(-directory) $pat \
  413.             $data(-showhidden)]} ] {
  414.         cd $appPWD
  415.         return
  416.         }
  417.     }
  418.     } else {
  419.     foreach pat $pattern {
  420.         if [catch {eval lappend files [glob -nocomplain $pat]}] {
  421.         cd $appPWD
  422.         return
  423.         }
  424.     }
  425.     }
  426.  
  427.     set oldfile {}
  428.     tixBusy $w on [$data(w:dirlist) subwidget hlist]
  429.  
  430.     foreach fname [lsort $files] {
  431.     if {![string compare . $fname] || ![string compare .. $fname]} {
  432.         continue
  433.     }
  434.     if {$fname == $oldfile} {
  435.         continue
  436.     }
  437.     if [file isdirectory $fname] {
  438.         continue
  439.     }
  440.     $listbox insert end $fname
  441.     set oldfile $fname
  442.     }
  443.     if {$data(oldDir) != $data(-directory)} {
  444.     # Otherwise if the user has already selected a file and then presses
  445.     # "show hidden", the selection won't be wiped out.
  446.     tixSetSilent $data(w:file) $data(-pattern)
  447.     }
  448.  
  449.     cd $appPWD
  450.     set data(oldDir) $data(-directory)
  451.  
  452.     tixWidgetDoWhenIdle tixBusy $w off [$data(w:dirlist) subwidget hlist]
  453. }
  454.  
  455. proc tixExFileSelectBox::CompressSlash {w dir} {
  456.     upvar #0 $w data
  457.  
  458.     return [tixFile trimslash [tixFile tildesubst $dir]]
  459. }
  460.  
  461. #
  462. # Called when thd listbox is first mapped
  463. proc tixExFileSelectBox::Map {w} {
  464.     if {![winfo exists $w]} {
  465.     return
  466.     }
  467.  
  468.     upvar #0 $w data
  469.  
  470.     tixExFileSelectBox::Cmd-DirList $w $data(-directory)
  471. }
  472.  
  473. #----------------------------------------------------------------------
  474. # Public commands
  475. #
  476. #----------------------------------------------------------------------
  477. proc tixExFileSelectBox::invoke {w} {
  478.     tixExFileSelectBox::Invoke $w
  479. }
  480.  
  481. proc tixExFileSelectBox::filter {w} {
  482.     tixExFileSelectBox::LoadFiles $w reload
  483. }
  484.  
  485.